package com.game.game.service.making;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.protobuf.GeneratedMessage;
import com.game.common.Transmitter;
import com.game.common.constants.GlobalConstants;
import com.game.core.db.service.proxy.EntityProxyFactory;
import com.game.core.net.common.RemoteNode;
import com.game.core.service.PublicService;
import com.game.core.service.ServiceContainer;
import com.game.game.service.item.ItemService;
import com.game.game.service.weapon.WeaponService;
import com.game.dbpersistence.game.entity.FashionEntity;
import com.game.dbpersistence.game.entity.ItemEntity;
import com.game.dbpersistence.game.entity.MakingEntity;
import com.game.dbpersistence.game.entity.WeaponEntity;
import com.game.game.GameServer;
import com.game.game.config.FashionConfig;
import com.game.game.config.ItemConfig;
import com.game.game.config.MakingConfig;
import com.game.game.config.WeaponConfig;
import com.game.game.config.WeaponStrengthenConfig;
import com.game.game.config.XMLTemplateService;
import com.game.message.proto.item.ItemProtoBuf;
import com.game.message.proto.making.MakingProtoBuf.GWMakeEquipmentRES;
import com.game.message.proto.making.MakingProtoBuf.GWSpeedEquipmentRES;
import com.game.message.proto.making.MakingProtoBuf.SpeedInfo;
import com.game.message.proto.making.MakingProtoBuf.WGMakeEquipmentREQ;
import com.game.message.proto.making.MakingProtoBuf.WGSpeedEquipmentREQ;
import com.game.message.protocol.ProtocolsConfig;

public class MakingService extends PublicService {

	private static final long serialVersionUID = 1L;
	private static Logger logger = LoggerFactory.getLogger(MakingService.class);

	public void sendMesToRemoteNode(RemoteNode remoteNode, GeneratedMessage message) {
		Transmitter.getInstance().write(remoteNode, GlobalConstants.DEFAULT_CALLBACK, message);
	}

	public GWMakeEquipmentRES makeEquipmentRequest(RemoteNode remoteNode, WGMakeEquipmentREQ message, int callback) {
		String ownerId = message.getAccount();
		int makingId = message.getMakingId();
		int operate = message.getOperate();
		GWMakeEquipmentRES.Builder res = GWMakeEquipmentRES.newBuilder();
		res.setAccount(ownerId);
		res.setOperate(operate);
		res.setMakingId(makingId);
		try {
			if (GameServer.makingEntityService == null) {
				GameServer.makingEntityService = GameServer
						.getMakingEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			MakingConfig makingConfig = XMLTemplateService.makingConfigMap.get(makingId);
			if (makingConfig == null) {
				res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_NOEXIST);
				return res.build();
			}
			ItemService itemService = ServiceContainer.getInstance().getPublicService(ItemService.class);
			// 停止取消制作 0 开始制作 1 制作完成 2
			if (operate == 0) {
				MakingEntity makingEntity = GameServer.makingEntityService.getMaking(ownerId, makingId);
				if (makingEntity != null) {
					boolean ret = GameServer.makingEntityService.deleteMaking(makingEntity);
					if (ret) {
						res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS);
					} else {
						res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
					}
				} else {
					res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_NOEXIST);
				}
			} else if (operate == 1) {
				MakingEntity makingEntity = GameServer.makingEntityService.getMaking(ownerId, makingId);
				if (makingEntity == null) {
					if (makingConfig.getType() == 1) {
						WeaponEntity weaponEntity = GameServer.weaponEntityService.getWeapon(ownerId, makingId);
						if (weaponEntity != null && weaponEntity.getOwnerId().equals(ownerId)) {
							res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_ALREADY_EXIST);
						}
					} else if (makingConfig.getType() == 2) {
						FashionEntity fashionEntity = GameServer.fashionEntityService.getFashion(ownerId,makingId);
						if (fashionEntity != null && fashionEntity.getOwnerId().equals(ownerId)) {
							res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_ALREADY_EXIST);
						}
					} else {
						ItemConfig itemConfig = XMLTemplateService.itemConfigMap.get(makingId);
						if((itemConfig!=null)&&(itemConfig.getType() == 4)){
							ItemEntity itemEntity = GameServer.itemEntityService.getItem(ownerId, makingId);
							if (itemEntity != null && itemEntity.getCount() > 0) {
								res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_ALREADY_EXIST);
							}
						}
					}
					if (res.getResult() != ProtocolsConfig.MAKE_EQUIPMENT_ALREADY_EXIST) {
						Map<Integer, Integer> consumeMap = new HashMap<>();
						consumeMap.put(makingConfig.getDrawing(), makingConfig.getDrawingNum());
						consumeMap.put(makingConfig.getPartA(), makingConfig.getNumA());
						consumeMap.put(makingConfig.getPartB(), makingConfig.getNumB());
						consumeMap.put(makingConfig.getPartC(), makingConfig.getNumC());					
							
						int ret = itemService.consumeItem(ownerId, consumeMap, ItemProtoBuf.SynItemType.MakeEquipmentConsume.ordinal());
						if (ret == ItemProtoBuf.ConsumeResultType.ConsumeSuccess.ordinal()) {
							makingEntity = new MakingEntity();
							makingEntity.setOwnerId(ownerId);
							makingEntity.setMakingId(makingId);
							makingEntity.setStartTime(System.currentTimeMillis());
							makingEntity.setStatus(2);
							makingEntity.setSpeedTime(0);
							long result = GameServer.makingEntityService.insertMaking(makingEntity);
							if (result > 0) {
								res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS);
							} else {
								res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
							}
						} else if (ret == ItemProtoBuf.ConsumeResultType.NotEnoughItem.ordinal()) {
							res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_UNENOUGH);
						} else if (ret == ItemProtoBuf.ConsumeResultType.ConsumeFail.ordinal()) {
							res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
						}
					}
				} else {
					res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_ALREADY);
				}
			} else if (operate == 2) {
				MakingEntity makingEntity = GameServer.makingEntityService.getMaking(ownerId, makingId);
				if (makingEntity != null) {
					long curTime = System.currentTimeMillis() / 1000;
					long startTime = makingEntity.getStartTime() / 1000;
					long speedTime = makingEntity.getSpeedTime();
					long time = makingConfig.getTime()*60;
					if (time <= (speedTime + (curTime - startTime))) {
						WeaponService weaponService = ServiceContainer.getInstance().getPublicService(WeaponService.class);
						if (makingConfig.getType() == 1) {
							WeaponConfig weaponConfig = XMLTemplateService.weaponConfigMap.get(makingId);
							if (weaponConfig != null) {
								WeaponEntity weaponEntity = new WeaponEntity();
								weaponEntity.setOwnerId(ownerId);
								weaponEntity.setWeaponId(makingId);
								weaponEntity.setName(weaponConfig.getName());
								weaponEntity.setWeaponType(weaponConfig.getWeaponType());
								weaponEntity.setWeaponLevel(weaponConfig.getWeaponLevel());
								// weaponEntity.setWeaponMaxLevel(weaponConfig.getWeaponMaxLevel());
								weaponEntity.setMainSkillId(weaponConfig.getMainSkillId());
								WeaponStrengthenConfig weaponStrengthenConfig = XMLTemplateService.weaponStrengthenConfigMap
										.get(makingId);
								if ((weaponStrengthenConfig != null)
										&& (weaponStrengthenConfig.getMainNodeList().size() > 0)) {
									weaponEntity.setMainNodeList(weaponStrengthenConfig.getMainNodeList());
								}
								long ret = GameServer.weaponEntityService.insertWeapon(weaponEntity);
								if (ret > 0) {
									res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS);
									weaponService.pushSynWeaponInfo(ownerId, weaponEntity, ItemProtoBuf.SynItemType.MakeEquipmentAdd.ordinal());
								} else {
									res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
								}
							}
						} else if (makingConfig.getType() == 2) {
							FashionConfig fashionConfig = XMLTemplateService.fashionConfigMap.get(makingId);
							if (fashionConfig != null) {
								FashionEntity fashionEntity = new FashionEntity();
								fashionEntity.setOwnerId(ownerId);
								fashionEntity.setFashionId(fashionConfig.getFashionId());
								fashionEntity.setUnlocked(fashionConfig.getStatus());
								fashionEntity.setHairColour(1);
								fashionEntity.setSkinColour(1);
								fashionEntity.setMainbodyColour(1);
								fashionEntity.setDecorateColour(1);
								fashionEntity.setSkinColours("[1]");
								fashionEntity.setHairColours("[1]");
								fashionEntity.setMainbodyColours("[1]");
								fashionEntity.setDecorateColours("[1]");
								
								long ret = GameServer.fashionEntityService.insertFashion(fashionEntity);
								if (ret > 0) {
									res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS);
									weaponService.pushSynFashionInfo(ownerId, fashionEntity, ItemProtoBuf.SynItemType.MakeEquipmentAdd.ordinal());
								} else {
									res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
								}
							}
						} else {
							Map<Integer, Integer> consumeMap = new HashMap<>();
							consumeMap.put(makingId, 1);
							long ret = itemService.addItem(ownerId, consumeMap ,ItemProtoBuf.SynItemType.MakeEquipmentAdd.ordinal());
							if (ret == ItemProtoBuf.AddResultType.AddSuccess.ordinal()) {
								res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS);
							} else if (ret == ItemProtoBuf.AddResultType.AddFail.ordinal()) {
								res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
							}
						}
						boolean ret = GameServer.makingEntityService.deleteMaking(makingEntity);
						if (ret) {
							res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS);
						} else {
							res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
						}
					} else {
						res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
					}
				} else {
					res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_NOEXIST);
				}
			} else {
				res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_NOEXIST);
			}
		} catch (Exception e) {
			logger.error(e.toString());
			res.setResult(ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_FAILED);
		}

		if (res.getResult() == ProtocolsConfig.MAKE_EQUIPMENT_OPERATE_SUCCESS) {
			List<MakingEntity> makingEntities = GameServer.makingEntityService.getMakingList(ownerId);
			if ((makingEntities != null) && (makingEntities.size() > 0)) {
				for (MakingEntity makingEntity : makingEntities) {
					res.addMakingInfos(makingEntity.toProto());
				}
			}
		}
		return res.build();
	}

	public GWSpeedEquipmentRES speedEquipmentRequest(RemoteNode remoteNode, WGSpeedEquipmentREQ message, int callback) {
		String accountId = message.getAccount();
		int makingId = message.getMakingId();
		List<SpeedInfo> speedInfosList = message.getSpeedInfosList();

		GWSpeedEquipmentRES.Builder res = GWSpeedEquipmentRES.newBuilder();
		res.setAccount(accountId);
		res.setMakingId(makingId);

		if ((speedInfosList == null) || (speedInfosList.size() <= 0)) {
			res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_FAILED);
			return res.build();
		}
		try {
			if (GameServer.makingEntityService == null) {
				GameServer.makingEntityService = GameServer.getMakingEntityProxyService(GameServer.classPathXmlApplicationContext);
			}
			MakingConfig makingConfig = XMLTemplateService.makingConfigMap.get(makingId);
			if (makingConfig == null) {
				res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_NOEXIST);
				return res.build();
			}

			ItemService itemService = ServiceContainer.getInstance().getPublicService(ItemService.class);
			if (itemService == null) {
				res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_FAILED);
				return res.build();
			}

			MakingEntity makingEntity = GameServer.makingEntityService.getMaking(accountId, makingId);
			if (makingEntity != null) {
				long speedTime = 0;
				long curTime = System.currentTimeMillis() / 1000;
				long startTime = makingEntity.getStartTime() / 1000;
				long hadSpeedTime = makingEntity.getSpeedTime();
				long time = makingConfig.getTime()*60;
				long remainTime = time - hadSpeedTime - (curTime - startTime);
				if ((remainTime > 0) && (speedInfosList != null) && (speedInfosList.size() > 0)) {
					int itemId1 = 0, itemId2 = 0, itemId3 = 0;
					long number1 = 0, number2 = 0, number3 = 0;
					long useage1 = 0, useage2 = 0, useage3 = 0;
					Map<Integer, Integer> consumeMap = new HashMap<>();
					for (SpeedInfo speedInfo : speedInfosList) {
						int itemId = speedInfo.getItemId();
						long number = speedInfo.getNumber();
						ItemConfig itemConfig = XMLTemplateService.itemConfigMap.get(itemId);
						long useage = Integer.parseInt(itemConfig.getUseage());
						int quality = itemConfig.getQuality();
						if (quality == 1) {
							itemId1 = itemId;
							number1 = number;
							useage1 = useage;
						} else if (quality == 2) {
							itemId2 = itemId;
							number2 = number;
							useage2 = useage;
						} else if (quality == 3) {
							itemId3 = itemId;
							number3 = number;
							useage3 = useage;
						}
					}

					if ((remainTime > 0)&&(number3 > 0)&&(remainTime >= number3 * useage3)) {
						speedTime = speedTime + useage3 * number3;
						consumeMap.put(itemId3, (int) number3);
						remainTime = remainTime - useage3 * number3;
					} else if ((remainTime > 0)&&(number3 > 0)&&(remainTime < number3 * useage3)){
						number3 = (remainTime / useage3) + 1;
						speedTime = speedTime + useage3 * number3;
						consumeMap.put(itemId3, (int) number3);
						remainTime = 0;
					}

					if ((remainTime > 0)&&(number2 > 0)&&(remainTime >= number2 * useage2)) {
						speedTime = speedTime + useage2 * number2;
						consumeMap.put(itemId2, (int) number2);
						remainTime = remainTime - useage2 * number2;
					} else if ((remainTime > 0)&&(number2 > 0)&&(remainTime < number2 * useage2)){
						number2 = (remainTime / useage2) + 1;
						speedTime = speedTime + useage2 * number2;
						consumeMap.put(itemId2, (int) number2);
						remainTime = 0;
					}

					if ((remainTime > 0)&&(number1 > 0)&&(remainTime >= number1 * useage1)) {
						speedTime = speedTime + useage1 * number1;
						consumeMap.put(itemId1, (int) number1);
						remainTime = remainTime - useage1 * number1;
					} else if ((remainTime > 0)&&(number1 > 0)&&(remainTime < number1 * useage1)){
						number1 = (remainTime / useage1) + 1;
						speedTime = speedTime + useage1 * number1;
						consumeMap.put(itemId1, (int) number1);
						remainTime = 0;
					}
					if ((speedTime > 0)&&(consumeMap.size() > 0)) {
						int ret = itemService.consumeItem(accountId, consumeMap ,ItemProtoBuf.SynItemType.SpeedEquipmentConsume.ordinal());
						if (ret == ItemProtoBuf.ConsumeResultType.ConsumeSuccess.ordinal()) {
							EntityProxyFactory entityProxyFactory = new EntityProxyFactory();
							MakingEntity proxyMakingEntity = entityProxyFactory.createProxyEntity(makingEntity);
							proxyMakingEntity.setSpeedTime(speedTime + hadSpeedTime);
							boolean result = GameServer.makingEntityService.updateMaking(proxyMakingEntity);
							if (result) {
								res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_SUCCESS);
							} else {
								res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_FAILED);
							}
						} else if (ret == ItemProtoBuf.ConsumeResultType.NotEnoughItem.ordinal()) {
							res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_UNENOUGH);
						} else {
							res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_FAILED);
						}
					}
				} else {
					res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_FAILED);
				}
			}
		} catch (Exception e) {
			res.setResult(ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_FAILED);
			logger.error(e.toString());
		}

		if (res.getResult() == ProtocolsConfig.SPEED_EQUIPMENT_OPERATE_SUCCESS) {
			List<MakingEntity> makingEntities = GameServer.makingEntityService.getMakingList(accountId);
			if ((makingEntities != null) && (makingEntities.size() > 0)) {
				for (MakingEntity makingEntity : makingEntities) {
					res.addMakingInfos(makingEntity.toProto());
				}
			}
		}
		return res.build();
	}

}
